
/*
  MeggyJr_MeggyChip
 MeggyChip: a game for two Meggy Jr RGB units, hooked together with a serial cable.
 
 Version 1.3 (beta) - 1/20/2009      http://www.evilmadscientist.com/
 Copyright (c) 2009 Chris Brookfield and Windell Oskay.  All right reserved.
 
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 
 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this library.  If not, see <http://www.gnu.org/licenses/>.
 	 
 */

  

#include <MeggyJrSimple.h>    // Required code, line 1 of 2.

#include <avr/pgmspace.h> 
   
#define SerialTimeout 8192   



// BEGIN FONT AND STRING DEFINITIONS  
// Font consists of A-Z, 0-9, +,-, .

const byte font_table[40][5] PROGMEM = 
{
  {
    15,20,20,15,0      }
  ,	//A
  {
    31,21,21,10,0      }
  ,	//B
  {
    14,17,17,10,0      }
  ,	//C
  {
    31,17,17,14,0      }
  ,	//D
  {
    31,21,21,17,0      }
  ,	//E

  {
    31,20,20,16,0      }
  ,	//F
  {
    14,17,21,22,0      }
  , 	//G
  {
    31,4,4,31,0      }
  ,  	//H
  {
    17,31,17,0,0      }
  , 	//I
  {
    2,1,1,30,0      }
  ,   	//J

  {
    31,4,10,17,0      }
  , 	//K
  {
    31,1,1,0,0      }
  ,   	//L
  {
    31,8,4,8,31      }
  ,  	//M
  {
    31,8,4,2,31      }
  ,  	//N
  {
    14,17,17,14,0      }
  ,    //O

  {
    31,20,20,8,0      }
  , 	//P
  {
    14,17,17,18,13      }
  ,	//Q
  {
    31,20,22,9,0      }
  , 	//R
  {
    9,21,21,21,18      }
  , 	//S
  {
    16,16,31,16,16      }
  ,	//T

  {
    30,1,1,30,0      }
  ,  	//U
  {
    28,2,1,2,28      }
  ,  	//V
  {
    31,2,4,2,31      }
  ,  	//W
  {
    17,10,4,10,17      }
  ,		//X
  {
    16,8,7,8,16      }
  ,  	//Y

  {
    17,19,21,25,17      }
  ,	//Z
  {
    14,17,17,14,0      }
  ,	//0
  {
    17,31,1,0,0      }
  ,  	//1
  {
    9,19,21,21,9      }
  ,  	//2
  {
    17,21,21,10,0      }
  ,	//3

  {
    28,4,31,4,0      }
  ,  	//4
  {
    29,21,21,18,0      }
  ,	//5
  {
    14,21,21,2,0      }
  , 	//6
  {
    16,19,20,24,0      }
  , 	//7
  {
    10,21,21,10,0      }
  ,	//8

  {
    8,21,21,14,0      }
  , 	//9
  {
    4,8,31,8,4      }
  ,		// +  (Up arrow used)
  {
    4,2,31,2,4      }
  ,		// -  (down arrow used)
  {
    0,0,0,0,0      }
  ,			//space
  {
    1,0,0,0,0      }	//decimal

}; 


const byte width_table[40] PROGMEM = 
{
  4,	//A
  4,	//B
  4,	//C
  4,	//D
  4,	//E

  4,	//F
  4,	//G
  4,	//H
  3,	//I
  4,	//J

  4,	//K
  3,	//L
  5,	//M
  5,	//N
  4,	//O

  4,	//P
  5,	//Q
  4,	//R
  5,	//S
  5,	//T

  4,	//U
  5,	//V
  5,	//W
  5,	//X
  5,	//Y

  5,	//Z
  4,	//0
  3,	//1
  5,	//2
  4,	//3

  4,	//4
  4,	//5
  4,	//6
  4,	//7
  4,	//8						 	

  4,	//9
  5,	// +
  5,	// -
  3,	//space
  1	//decimal

}; 



const char String0[] PROGMEM = "MEGGYCHIP    A GAME FOR TWO MEGGIES   ;";  

const char String1[] PROGMEM = "PLACE THE PARTS ON YOUR MOTHERBOARD   ;";

const char String2[] PROGMEM = " TRANSISTOR;";
const char String3[] PROGMEM = " SPEAKER;";
const char String4[] PROGMEM = " OSCILLATOR;";
const char String5[] PROGMEM = " LED DRIVER CHIP;";
const char String6[] PROGMEM = " MICROCONTROLLER;";

const char String7[] PROGMEM  = "  ATTACK  ;";
const char String8[] PROGMEM =  "  DEFEND  ;";
const char String9[] PROGMEM  = "YOU SHORTED OUT THE ENEMY ;";
const char String10[] PROGMEM = "  YOUR HAVE LOST YOUR ;";
const char String11[] PROGMEM = "GAME OVER  ;"; 
const char String12[] PROGMEM = "YOU WIN   YOU WIN   YOU WIN ;"; 
const char String13[] PROGMEM = "WAITING  ;";
const char String14[] PROGMEM = "PLACE YOUR ;";
const char String15[] PROGMEM = "W;";
const char String16[] PROGMEM = "A;";
const char String17[] PROGMEM = "I;";
const char String18[] PROGMEM = "T;";
const char String19[] PROGMEM = "I;";
const char String20[] PROGMEM = "N;";
const char String21[] PROGMEM = "G ;"; 

char buf[38];				//Set number of characters per string: this eats SRAM!

#define NoOfStrings1 13U

PGM_P StringSet[] PROGMEM = 
{String0,  String1,  String2,  String3,  String4, 
 String5,  String6,  String7,  String8,  String9, 
 String10, String11, String12, String13, String14,
 String15, String16, String17, String18, String19, String20, String21, }; 


byte TextScroll(byte StringNo, byte color, byte textDelay_ms, byte AllowBreak, byte AllowSerialBreak)
{
PGM_P p;	
byte StringPosition = 0;  
char StringChar, FontChar;
byte CharWidth, SubCharPos, SubCharWord, x, escape;
unsigned long LastTime = millis();
memcpy_P(&p, &StringSet[StringNo], sizeof(PGM_P));
strcpy_P(buf, p);	

escape = 0;

  while( buf[StringPosition] != ';' )	
  { 
    StringChar = buf[StringPosition];
 
   if (StringChar >= 'A')	
  {
    FontChar = StringChar - 'A';
  }

  if (StringChar == ' ')
    FontChar = 38;
  if (StringChar == '+')	
    FontChar = 36;
  if (StringChar == '-')	
    FontChar = 37;			
  if (StringChar == '.')	
    FontChar = 39;			

  if ((StringChar >= '0') && (StringChar <= '9'))	
    FontChar = StringChar - '0' + 26;	

  // New character is picked now.  

  CharWidth = (uint8_t)pgm_read_word(&width_table[FontChar]);  
 
  SubCharPos = 0;
 while (SubCharPos <=  CharWidth)
 {

    if (SubCharPos == CharWidth)
      SubCharWord = 0;   // ending gap
    else	
      SubCharWord = (uint8_t)pgm_read_word(&font_table[FontChar][SubCharPos]); 
 
    SubCharWord <<= 2;

    // Scrolling part:
    x = 0;
    while (x < 7)
    {

      DrawPx(x,0, ReadPx(x+1,0));
      DrawPx(x,1, ReadPx(x+1,1));
      DrawPx(x,2, ReadPx(x+1,2));
      DrawPx(x,3, ReadPx(x+1,3));
      DrawPx(x,4, ReadPx(x+1,4));
      DrawPx(x,5, ReadPx(x+1,5));
      DrawPx(x,6, ReadPx(x+1,6));
      DrawPx(x,7, ReadPx(x+1,7));

      x++;
    }

    if (SubCharWord & 1)
      DrawPx(7,0,color); 
    else
      DrawPx(7,0,Dark);  

    if (SubCharWord & 2)
      DrawPx(7,1,color); 
    else
      DrawPx(7,1,Dark);  

    if (SubCharWord & 4)
      DrawPx(7,2,color); 
    else
      DrawPx(7,2,Dark);  

    if (SubCharWord & 8)
      DrawPx(7,3,color); 
    else
      DrawPx(7,3,Dark);  

    if (SubCharWord & 16)
      DrawPx(7,4,color); 
    else
      DrawPx(7,4,Dark);  

    if (SubCharWord & 32)
      DrawPx(7,5,color); 
    else
      DrawPx(7,5,Dark);  

    if (SubCharWord & 64)
      DrawPx(7,6,color); 
    else
      DrawPx(7,6,Dark);  

    if (SubCharWord & 128)
      DrawPx(7,7,color); 
    else
      DrawPx(7,7,Dark);  
 
      DisplaySlate();      // Write the updated game buffer to the screen.
      
     while (( millis() - LastTime) < textDelay_ms)
    {  
       if (AllowBreak)
        {
            CheckButtonsPress();
        if (Button_A)  
           escape = 1; 
       }
       if (AllowSerialBreak)
          if (Serial.available() > 0)
             escape = 1; 
       
    } 
       if ((escape) && (textDelay_ms > 2))
       textDelay_ms >>= 1;
        
      LastTime = millis();
    
    SubCharPos++;
  } 
     StringPosition++;
  } 
  
  return escape;
}



// Global vars:	
unsigned char columns[8];	

void getSerialChar(byte &theChar, byte &timedOut){ 
  if (timedOut == 0)
  {
    unsigned int i = 0;
    byte WaitForData = 1;  

    while (WaitForData)   // give up if we don't get data in a certain amount of time
    {
      if (Serial.available() > 0)
      {
        WaitForData = 0; 
        theChar = Serial.read();
      } 
      else if (++i > SerialTimeout)
      {
        WaitForData = 0;  
        timedOut = 1;
      }
    }   // end "while (WaitForData)" 
  }
  return; 
}

void splashscreen(void){
  while ( TextScroll(0, Orange, 100, 1,0) == 0)
   {}
   ClearSlate();
   DisplaySlate;
   delay(500);
  
}
 
byte k;
byte xpos;
byte ypos;

byte xposTemp, yposTemp;

byte m;
byte boatSize;
byte boatDirec;
byte xLimit;
byte yLimit;
byte boatDraw;
byte MyTurn = 0;
byte DelayTime_ms = 100;        // define a delay time between cursor on/off

unsigned long LastTime;          // long variable for millisecond counter storage

struct shipsection
{
  byte xpos;
  byte ypos;
  byte color;
  byte shipNo;
};

struct shipsection fleet[15];

byte TargetArray[8][8];
byte Misses[8];  //Where the other player tried but missed.

byte ShipsPlaced;
byte CommEstablished;
long TimeStamp;

byte sink;


void gamesetup()
{

  byte i,j;

  Serial.flush();

CheckButtonsPress();

  xpos = 2;
  ypos = 2;
  m = 0;
  boatSize = 5;
  boatDirec = 0;
  xLimit = 0;
  yLimit = 0;
  boatDraw = 0;

  splashscreen();
 
 TextScroll(1, Green, 90, 1,0);      // Place chips on board
 
// TextScroll(14, Orange, 80, 1,0);    //Place your
 TextScroll(6, Orange, 80, 1,0);    //microcontroller
  
sink = 0;

  i = 0;
  while (i < 15)
  {
    fleet[i].xpos = 7;
    fleet[i].ypos = 7;
    fleet[i].color = 0;
    i++;
  }

  ShipsPlaced = 0;
  CommEstablished = 0;

  i = 0;
  j = 0;

  while (i < 8)
  {
    j = 0;
    while (j < 8)
    {
      TargetArray[i][j] = 0;
      j++;
    } 

    Misses[i] = 0;
    i++;
  }
 
}

void setup()                    // run once, when the sketch starts
{
  
EditColor(DimGreen, 0, 5, 0);    // Brighter than usual "dim green"

//EditColor(22, 11, 3, 0);
//EditColor(21, 11, 2, 0);
//EditColor(20, 11, 1, 0);
EditColor(19, 15, 3, 0);
EditColor(18, 11, 2, 0);
EditColor(17, 7, 1, 0);
EditColor(16, 3, 0, 0);
 
  // start serial port:
  Serial.begin(9600);
 
  MeggyJrSimpleSetup();      // Required code, line 2 of 2.


gamesetup();


}  // End setup()

/*
Game Phases:
 
 A. Place ships
 B. Establish Communication
 C. Gameplay proper
 
 */


void loop()                     // run over and over again
{   
  
LoopStart:
  
  // Debug options:
//    ShipsPlaced = 1;
//  CommEstablished = 1;
// MyTurn = 1;

  byte i,j; 
  byte inByte;
  byte inByte1, inByte2;
  byte timeout;
  byte CursorPhase = 10;
 
int8_t temp = 0;

  CheckButtonsPress();


  if (ShipsPlaced == 0)
  {
    if (Button_B)      // place ship
    {
      m = 0;
      while (m < 15)
      {
        if (boatDirec == 0)
        {
          k = 0;
          while (k < boatSize)
          {
            if (fleet[m].xpos == (xpos)) 
              if (fleet[m].ypos == (ypos+k))
                if (fleet[m].color == DimGreen)
                  boatDraw = 1;
            k++;
          }
        }
        else
        {
          k = 0;
          while (k < boatSize)
          {
            if (fleet[m].ypos == (ypos)) 
              if (fleet[m].xpos == (xpos+k))
                if (fleet[m].color == DimGreen)
                  boatDraw = 1;
            k++;
          }
        }
        m++;    
      }

      if (boatDraw == 1)
      {
        m = 0;
        while (m < boatSize)
        {
          if (boatDirec == 0)
            DrawPx(xpos,ypos+m,Red);
          else
            DrawPx(xpos+m,ypos,Red);
          m++;
        }
        DisplaySlate();
        delay(100);
      }

      if (boatDraw == 0)
      {

        k = 0;
        while (k < boatSize)
        {

          if (boatSize == 1)
          {

            if (boatDirec == 0)  
              fleet[14].ypos = (ypos + k);
            else  
              fleet[14].ypos = (ypos);

            if (boatDirec == 1)  
              fleet[14].xpos = (xpos + k);
            else  
              fleet[14].xpos = (xpos);

            fleet[14].color = DimGreen;
            fleet[14].shipNo = boatSize;
          }


          if (boatSize == 2)
          {


            if (boatDirec == 0) 
            {
              fleet[12+k].xpos = (xpos);
              fleet[12+k].ypos = (ypos + k);
            }
            else
            {
              fleet[12+k].xpos = (xpos + k);
              fleet[12+k].ypos = (ypos);
            }
 

            fleet[12+k].color = DimGreen;
            fleet[12+k].shipNo = boatSize;
          }

          if (boatSize == 3)
          {

            if (boatDirec == 0) 
            {
              fleet[9+k].xpos = (xpos);
              fleet[9+k].ypos = (ypos + k);
            }
            else
            {
              fleet[9+k].xpos = (xpos + k);
              fleet[9+k].ypos = (ypos);
            } 
            fleet[9+k].color = DimGreen;
            fleet[9+k].shipNo = boatSize;
          }

          if (boatSize == 4)
          {
            if (boatDirec == 0) 
            {
              fleet[5+k].xpos = (xpos);
              fleet[5+k].ypos = (ypos + k);
            }
            else
            {
              fleet[5+k].xpos = (xpos + k);
              fleet[5+k].ypos = (ypos);
            } 
            fleet[5+k].color = DimGreen;
            fleet[5+k].shipNo = boatSize;
          }


          if (boatSize == 5)
          {
            if (boatDirec == 0) 
            {
              fleet[k].xpos = (xpos);
              fleet[k].ypos = (ypos + k);
            }
            else
            {
              fleet[k].xpos = (xpos + k);
              fleet[k].ypos = (ypos);
            } 
            fleet[k].color = DimGreen;
            fleet[k].shipNo = boatSize;
          }
          k++;
        }

        Tone_Start( ToneA6, 40);

        j = 0;
        while (j < 3)
        {
          m = 0;
          while (m < 15)
          {
            if (fleet[m].shipNo == boatSize)
              DrawPx(fleet[m].xpos,fleet[m].ypos,White);
            m++;
          }
          DisplaySlate();
          delay(100);

          m = 0;
          while (m < 15)
          {
            if (fleet[m].shipNo == boatSize)
              DrawPx(fleet[m].xpos,fleet[m].ypos,DimGreen);
            m++;
          }
          DisplaySlate();
          delay(100);
          j++;
        }

        ypos = 7;
        xpos = 0;
  
         
         if ( boatSize >= 2)
         TextScroll(boatSize, Violet, 75, 1,0);    //boat
  
        boatSize--; 
         
      }
      boatDraw = 0;  
    }

    if (Button_A)          //rotate ship
    { 
      if (boatDirec == 0) 
        boatDirec = 1; 
      else
        boatDirec = 0;
    }

    if (Button_Up)      // up button
      if (ypos < (8-yLimit))
        if (yLimit > 0) 
          ypos++; 
        else
          if (ypos < 7)
            ypos++;

    if (Button_Down)  // down button
        if (ypos > 0) 
        ypos--;  

    if (Button_Left)  // left button
      if (xpos > 0) 
        xpos--; 

    if (Button_Right)  // right button
      if (xpos < (8-xLimit))
        if (xLimit > 0)
          xpos++; 
        else
          if (xpos < 7)
            xpos++;

    boatDraw = 0;
    ClearSlate();


    m = 0;
    while (m < 15)
    {
      if (boatDirec == 0)
      {
        k = 0;
        while (k < boatSize)
        {
          if (fleet[m].xpos == (xpos)) 
            if (fleet[m].ypos == (ypos+k))
              if (fleet[m].color == DimGreen)
                boatDraw = 1;
          k++;
        }
      }
      else
      {
        k = 0;
        while (k < boatSize)
        {
          if (fleet[m].ypos == (ypos)) 
            if (fleet[m].xpos == (xpos+k))
              if (fleet[m].color == DimGreen)
                boatDraw = 1;
          k++;
        }
      }
      m++;   
    }

    DrawPx(xpos,ypos,4-(boatDraw));

    if (boatSize == 0)
    {
      DrawPx(xpos,ypos,Dark);
      ShipsPlaced = 1;
    }

    k = 0;
    while (k < 15)      // Draw all elements of the fleet:
    {
      if (fleet[k].color > 0)  
        DrawPx(fleet[k].xpos,fleet[k].ypos,fleet[k].color);
      k++;
    }


    if (boatDirec == 0)
    {
      yLimit = boatSize;
      xLimit = 0;
      k = 0;
      while (k < boatSize)
      {
        if (ypos+k<8)
        {
          DrawPx(xpos,ypos+k,4-(boatDraw));
          k++;
        }
        else
          ypos--;
      }
    }
    else
    {
      yLimit = 0;
      xLimit = boatSize;
      k = 0;
      while (k < boatSize)
      {
        if (xpos+k<8)
        { 
          DrawPx(xpos+k,ypos,4-(boatDraw));
          k++;
        }
        else
          xpos--;
      }
    }

    DisplaySlate();

  } // End "if (ShipsPlaced == 0)
  else // Ships are now placed
  {
    if (CommEstablished == 0)
    {
      j = 0;
      k = 0;

      Serial.flush();
      TimeStamp = millis();

 
 
 
 k = 15;
      while (CommEstablished == 0)
      {

        if (Serial.available() > 0) {
          inByte = Serial.read();

          if (inByte == 'R')
          {
            Serial.print('B', BYTE);     // We will go second
            CommEstablished = 1; 
          }
          if (inByte == 'B')
          {
            Serial.print('P', BYTE);     // We will go First
            CommEstablished = 1;
            MyTurn = 1;
          }      

        }
        else
        {
          if    ((millis() - TimeStamp) > 500)
          {
            Serial.print('R', BYTE);     // Attempt to initiate communication 
          }

        }
        
        TextScroll(k, White, 50, 0, 1); // Waiting message
       
       k++;
       if (k > 21)
       {
       k = 15;
       Tone_Start(ToneB2, 50);
       }
  //      delay(100);

      }

    }
    else 
    {
    
      // Time For GamePlay!
      SetAuxLEDs(0);
      LastTime = millis();
     xpos = 3;
     ypos = 3;
     xposTemp = xpos;
     yposTemp = ypos;
      
     k = 0;
     while (k < 15)
     {
     fleet[k].color = Green; 
     k++;
     }
     
     if  (MyTurn)
       TextScroll(7, Violet, 75, 1,0); // Attack message
     else
       TextScroll(8, Orange, 75, 1,0); // Defend message
  
       
     while (sink < 5)    
     {
     
      if (MyTurn)
      {    
         /////////////////////////// Attack Mode:  ///////////////////////////
        
 
//     ClearSlate();
            
  i = 0;
  j = 0;

  while (i < 8)
  {
    j = 0;
    while (j < 8)
    {
       k = TargetArray[i][j];
       
       if (k > 128)
       DrawPx(i,j,Red); 
      else if (k == 64) 
       DrawPx(i,j,White); 
      else if (k > 0)
       DrawPx(i,j,Orange); 
      else
        DrawPx(i,j,Dark);      
       
      j++;
    }  
    i++;
  }
  
  
       CheckButtonsPress();
 
    if (Button_Up)      // up button 
      if (ypos < 7) 
          ypos++;   
    
    if (Button_Down)  // down button
        if (ypos > 0) 
        ypos--;  

    if (Button_Left)  // left button
      if (xpos > 0) 
        xpos--; 

    if (Button_Right)  // right button
      if (xpos < 7)
          xpos++;
 
  if (TargetArray[xpos][ypos] == 0) 
      DrawPx(xpos,ypos,DimViolet);   
 
 // Draw cursor crosshairs:  
 if (CursorPhase <= 4)
 { 
   
       temp = xposTemp + CursorPhase; 
      if (temp < 8)
          DrawPx(temp,yposTemp,CursorPhase + 16); 
  
      temp = xposTemp - CursorPhase; 
      if (temp >= 0)
          DrawPx(temp,yposTemp,CursorPhase + 16);         
 
      temp = yposTemp + CursorPhase; 
      if (temp < 8)
          DrawPx(xposTemp,temp,CursorPhase + 16); 
  
      temp = yposTemp - CursorPhase; 
      if (temp >= 0)
          DrawPx(xposTemp,temp,CursorPhase + 16);          
 }
     
  if ((millis() - LastTime) > DelayTime_ms)    // Check for time elapsed to blink cursor.
  { LastTime = millis();
  
  if ( CursorPhase > 1)
    CursorPhase--;  
  else 
     CursorPhase = 6;     
     
    if (CursorPhase >= 3)
    {
    xposTemp = xpos;
    yposTemp = ypos;
    }
    
      DelayTime_ms = 12*CursorPhase;   
  }
  
       DisplaySlate();
  
 
   if ((Button_A) || (Button_B))         //FIRE
    { 
  if (TargetArray[xpos][ypos] == 0)  // Send Fire Signal
    {   
     
     while (Serial.available() == 0)
      {
      Serial.print('F', BYTE);   // Initiate Fire Sequence
      Serial.print(xpos, BYTE);   // send x-coordinate 
      Serial.print(ypos, BYTE);   // send y-coordinate   
      Serial.print('f', BYTE);   //End Fire Sequence    
      delay(50);
      }
    
     inByte = Serial.read();        
     
          if (inByte == 'H'){  // Hit!
       
          k = 0;    
            while (k < 250)
          {   
            if (Serial.available() > 0)
              break; 
            delay(1);
             k++;
          }      

          inByte2 = Serial.read();        // Read ship number   

          TargetArray[xpos][ypos] = inByte2;    // Label with ship number
          
          Tone_Start(ToneA5,40);          
          }
          else if (inByte == 'S'){  // Sink!
   
          k = 0;    
            while (k < 250)
          {   
            if (Serial.available() > 0)
              break; 
            delay(1);
             k++;
          }      

          inByte2 = Serial.read();        // Read ship number   
          TargetArray[xpos][ypos] = inByte2;    // Label with ship number
                                
           i = 0; 
          
           while (i < 8)
           {
            j = 0;
             while (j < 8)
                {
                  if (TargetArray[i][j] == inByte2)
                      TargetArray[i][j] = 128 + inByte2;     // Label as sunk       
                  j++;
                }  
               i++;
             }
           
          Tone_Start(ToneA5,100);
          delay(100);
          Tone_Start(ToneB2,40);
          sink++;
          }         
          else if (inByte == 'M'){  // Miss!
          TargetArray[xpos][ypos] = 64;   // Label as miss
          Tone_Start(ToneB2,40);
          }             
//          else
//          TargetArray[xpos][ypos] = 0;  //  
          
          MyTurn = 0;
          Serial.flush();
         
 ClearSlate();
 k = 0;

while (k < 10)
{
  i = 0;  
  while (i < 8)
  {
    j = 0;
    while (j < 8)
    { 
       
      if (TargetArray[i][j] > 128)
         DrawPx(i,j,Red); 
      else if (TargetArray[i][j] == 64) 
         DrawPx(i,j,White); 
      else if (TargetArray[i][j] > 0)
         DrawPx(i,j,Orange); 
       
     if ((k < 9) && (k & 1))
       {
        if (inByte == 'S') 
          {
           if (TargetArray[i][j] == (128 + inByte2))
              DrawPx(i,j,Orange); 
          }
     else {     //'H' or 'M'
            DrawPx(xpos,ypos,Dark); 
        }
        
      }  
      
      j++;
    }  
    i++;
  }
  DisplaySlate();
  delay(100); 
  k++;
}
  
    } 
  }
           
            
 if (sink >= 5) 
 {
     // We've Won!!!
     
      while (TextScroll(12, Green, 90, 1,0) == 0)
 {   } 
       gamesetup();  
       goto LoopStart;
     
 } 
           
           
           
           
      }
      else
      {      /////////////////////////// Defense Mode:  ///////////////////////////

        ClearSlate();
 
        k = 0;
        while (k < 15)      // Draw all elements of the fleet:
        {
          if (fleet[k].color > 0)  
            DrawPx(fleet[k].xpos,fleet[k].ypos,fleet[k].color);
          k++;
        }

        // Draw misses, if any:

        k = 0;
        while (k < 8)
        {
          i = 0;
          while (i < 8)
          {
            if (Misses[k] & (128 >> i))
              DrawPx(i,k,White);  
            i++;
          } 
          k++;
        }
 
        DisplaySlate();
 
        // Expecting 'Fxyf' where x and y are bytes giving position.

        if (Serial.available() > 0) {
          inByte = Serial.read();        
          if (inByte == 'F')
          {
            timeout = 0; 

            inByte1 = 255;
            inByte2 = 255; 

            getSerialChar(inByte1, timeout);    // x
            getSerialChar(inByte2, timeout);    // y
            getSerialChar(inByte, timeout);

            // Now check the 3 numbers for sanity:

            byte SyntaxOK = 1;

            if (inByte1 > 7)
              SyntaxOK = 0;
            if (inByte2 > 7)
              SyntaxOK = 0;       

            if ((SyntaxOK == 0) || (timeout))
              Serial.flush(); 
            else if (inByte == 'f')
            {   // Firing event detected successfully.
              // Check for hit.
 
              byte hit = 0;     
              byte ShipHit = 0;

              k = 0;
              while (k < 15)      // Draw all elements of the fleet:
              { 
                if ((fleet[k].xpos == inByte1) && (fleet[k].ypos == inByte2))
                {
                  hit = 1;      // position is hit
                  
                  if (fleet[k].color == Green)
                    hit = 2;     // was not hit before.

                  fleet[k].color = Orange;
                  ShipHit = fleet[k].shipNo;
                }
                k++;
              }
 
              if (hit == 2)    // Check for sinking, because we just turned a dot from green to orange..
              { 
                k = 0;
                while (k < 15)      // Search elements of the fleet:
                {
                  if (fleet[k].shipNo == ShipHit)
                  {
                    if (fleet[k].color == Green)
                      hit = 1;     // A green dot still exists on that ship!  => Not sunk yet...
                  }
                  k++;
                } 
              }
 
              if (hit == 0)    {
                Serial.print('M', BYTE);   // Report Miss  
                Misses[inByte2] |= (128 >> inByte1);  
              }  
              else if (hit == 1)   {
                Serial.print('H', BYTE);     // Report Hit  
                Serial.print(ShipHit, BYTE);     // Report Hit                 
              }
              else   { 
                Serial.print('S', BYTE);     // Report Sink 
                Serial.print(ShipHit, BYTE);     // Report which ship is sunk.  
                
                  k = 0;
                while (k < 15)      // Search elements of the fleet:
                {
                  if (fleet[k].shipNo == ShipHit) 
                      fleet[k].color = Red;     // Relabel sunk ship in red.  
                  k++;
                }  
              }
               
 j = 0;
 while (j < 10)      // Should blink dot that was fired at in this section!
 {
              k = 0;
              while (k < 15)      // Draw all elements of the fleet:
              {
                if (fleet[k].color > 0)  
                  DrawPx(fleet[k].xpos,fleet[k].ypos,fleet[k].color);
                k++;
              }
 
              // Draw misses, if any: 
              k = 0;
              while (k < 8)
              {
                i = 0;
                while (i < 8)
                {
                  if (Misses[k] & (128 >> i))
                    DrawPx(i,k,White);  
                  i++;
                } 
                k++;
              }
              
            if ((j < 9) && (j & 1))
              DrawPx(inByte1,inByte2,Dark);     // Blink off
               
              DisplaySlate();
              delay(100); 
              j++;
 }
 
              MyTurn = 1;
            }
            else
              Serial.flush(); 

          }      // End " if (inByte == 'F')"

        }
        else
          delay(13);
 
 
 // End of turn: Check to see if we've lost:
                 j = 0;
                 k = 0;
                while (k < 15)      // Search elements of the fleet:
                { 
                    if (fleet[k].color == Green)
                      j = 1;     // A green dot still exists!
                  k++;
                } 
 
 if (j == 0)
 {
 // We've lost!!!
  
 while (TextScroll(11, Red, 90, 1,0) == 0)
 {   } 
       gamesetup();  
       goto LoopStart;
 
 }
 
  
 
      }
    }
     
    }   
    
  }

}
